package com.strongbj.iot.devices.guis.respnose.handle;

import java.io.UnsupportedEncodingException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.common.AbstractTaskDelayedRunnable;
import com.strongbj.iot.devices.dam.common.DAMManager;
import com.strongbj.iot.devices.dam.common.ITaskManager;
import com.strongbj.iot.devices.dam.request.entity.ScreenCommandEntity;
import com.strongbj.iot.devices.guis.message.GUISMessage;
import com.strongbj.iot.devices.guis.message.GUISOSMessageFactory;
import com.strongbj.iot.devices.guis.message.MQMessageOfGUIS;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.internal.StringUtil;

/**
 * 解析"上位机获取主机网络配置信息"回复报文
 * 
 * @author 25969
 *
 */
public class GUISGetHostNetworkInfoHandle implements IMessageHandle<GUISMessage, Object> {
	private static Logger logger = LogManager.getLogger(GUISGetHostNetworkInfoHandle.class.getName());
	private static final byte SCREEN_ID = (byte) 4; // 网络屏幕ID
	private static final byte LOCAL_IP_TEXT_ID = (byte) 1; // IP控件ID（文本框在屏幕中的ID）
	private static final byte LOCAL_MASK_TEXT_ID = (byte) 2; // 子网掩码控件ID（文本框在屏幕中的ID）
	private static final byte LOCAL_GATEWAY_TEXT_ID = (byte) 3; // 网关控件ID（文本框在屏幕中的ID）
	private static final byte SERVER_IP_TEXT_ID = (byte) 4; // IP控件ID（文本框在屏幕中的ID）
	private static final byte SERVER_PORT_TEXT_ID = (byte) 5; // 子网掩码控件ID（文本框在屏幕中的ID）
//	private TopicSender topicSender = (TopicSender) ContextUtils.getBean("topicSender");
	private static final String STRING_CODE = "GBK";
	private GUISOSMessageFactory guisMessageFactory = new GUISOSMessageFactory();

	@Override
	public boolean isHandle(GUISMessage t) {
		if (Integer.valueOf("22", 16).byteValue() == t.getCommand()) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, GUISMessage t) {
		// 6byte(本机MAC地址)+4byte(本机IP地址)+4byte(本机掩码)+4byte(本机网关)+4byte(本机dns)+2byte(本机端口号)+4byte（目标IP地址）+2byte（目标端口号）

		String macAddress = ByteUtil.byteArrToHexString(t.getData(), 3, 6); // 6个字节mac地址
		int nativeIPAddress = ByteUtil.bytesToInt(t.getData(), 9); // 本机IP地址

		int subnetMask = ByteUtil.bytesToInt(t.getData(), 13);// 本机掩码
		int dns = ByteUtil.bytesToInt(t.getData(), 21);// 本机dns
		int targetPort = ByteUtil.byteArrToShort(t.getData(), 29);// 目标端口号

		String ip = ByteUtil.bytesToUbyte(t.getData(), 9) + "." + ByteUtil.bytesToUbyte(t.getData(), 10) + "."
				+ ByteUtil.bytesToUbyte(t.getData(), 11) + "." + ByteUtil.bytesToUbyte(t.getData(), 12);
		// 在网络设置屏幕中设置子网掩码显示框显示的值
		String mask = ByteUtil.bytesToUbyte(t.getData(), 13) + "." + ByteUtil.bytesToUbyte(t.getData(), 14) + "."
				+ ByteUtil.bytesToUbyte(t.getData(), 15) + "." + ByteUtil.bytesToUbyte(t.getData(), 16);
		// 在网络设置屏幕中设置子网关显示框显示的值
		String gateway = ByteUtil.bytesToUbyte(t.getData(), 17) + "." + ByteUtil.bytesToUbyte(t.getData(), 18) + "."
				+ ByteUtil.bytesToUbyte(t.getData(), 19) + "." + ByteUtil.bytesToUbyte(t.getData(), 20);
		String serverIp = ByteUtil.bytesToUbyte(t.getData(), 25) + "." + ByteUtil.bytesToUbyte(t.getData(), 26) + "."
				+ ByteUtil.bytesToUbyte(t.getData(), 27) + "." + ByteUtil.bytesToUbyte(t.getData(), 28);
		logger.info("收到RU2000上传的主机网络配置信息 回复报文   mac地址：" + macAddress + " 本机IP地址:" + nativeIPAddress + " 本机掩码:" + subnetMask
				+ " 本机网关:" + gateway + " 本机dns:" + dns + " 目标IP地址:" + serverIp + " 目标端口号:" + targetPort);

		ITaskManager taskManager = DAMManager.getTaskManager(ByteUtil.byteArrToHexString(t.getHostNumber()));
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				try {
					sendMessage(ctx, t.getHostNumber(), SCREEN_ID, LOCAL_IP_TEXT_ID, ip, LOCAL_MASK_TEXT_ID, mask,
							LOCAL_GATEWAY_TEXT_ID, gateway,
							SERVER_IP_TEXT_ID,serverIp,
							SERVER_PORT_TEXT_ID,String.valueOf(targetPort));
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
//				try {
//					Thread.sleep(500);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
			}
		});
		return null;
	}

//	/**
//	 * 推送主机网络配置信息数据
//	 * @param hostNumber
//	 */
//	private void pushToMq(String hostNumber,String nativeIPAddress,String subnetMask,String gateway,String targetIaddressIp,String targetPort,String macAddress,String dns) {
//		GUISMQMessage mes = new GUISMQMessage();
//		   mes.setActioncode("reader031");
//		   UInfoEntity u = new UInfoEntity();
//		   u.setDevAddrCode(hostNumber);
//		   u.setSubnetMask(subnetMask);
//		   u.setDns(dns);
//		   u.setGateway(gateway);
//		   u.setNativeIPAddress(nativeIPAddress);
//		   u.setTargetIaddressIp(targetIaddressIp);
//		   u.setTargetPort(targetPort);
//		   u.setMacAddress(macAddress);
//		   mes.setAwsPostdata(u); 
//		  String json = JSON.toJSONString(mes);
//		   logger.info("GUIS 向MQ推送 [主机网络配置信息数据] 的json  "+json); 
//		   topicSender.send("daioReader", json);
//	}
//	

	private void sendMessage(ChannelHandlerContext ctx, byte[] devAddress, byte screenId, byte ipControlId,
			String ipContent, byte maskControlId, String maskContent, byte gatewayControlId, String gatewayContent,
			byte serverIpControlId, String serverIpContent,
			byte portControlId, String port)
			throws UnsupportedEncodingException {
		byte[] datas = createUpdateTextControlMessage(devAddress, screenId, ipControlId, ipContent, maskControlId,
				maskContent, gatewayControlId, gatewayContent,serverIpControlId,serverIpContent,portControlId,port);
		
		MQMessageOfGUIS mm = new MQMessageOfGUIS();
		ScreenCommandEntity sc = new ScreenCommandEntity();
		sc.setRackConverCode(ByteUtil.byteArrToHexString(devAddress));
		sc.setCommand(StringUtil.toHexString(datas));
		mm.setAwsPostdata(JSON.toJSONString(sc));

		final Channel channel = ctx.channel();
		sendDatasToRU2000(channel, sc.getRackConverCode(), ByteUtil.hexStringToBytes(sc.getCommand()));
	}
	private void sendDatasToRU2000(Channel channel, String devCode, byte[] datas) {
		if (channel != null && channel.isActive()) {
			// 将命令发送到屏幕硬件
			final byte[] retDatas = guisMessageFactory.createGUISOSMessage(ByteUtil.hexStringToBytes(devCode),
					(byte) 0x31, datas);
			logger.info("预下发显示本地网卡参数命令到屏幕 编号:{} 命令={}  ", devCode, ByteUtil.byteArrToHexString(retDatas));
			ByteBuf bs = Unpooled.copiedBuffer(retDatas);
			ChannelFuture cf = channel.writeAndFlush(bs);

			cf.addListener(new ChannelFutureListener() {

				@Override
				public void operationComplete(ChannelFuture future) throws Exception {
					if (future.isSuccess()) {
						logger.info("向屏幕下发设置本地网卡参数到文本控件命令成功 下发命令={}", devCode, ByteUtil.byteArrToHexString(datas, true));
					} else {
						logger.error("向屏幕下发设置本地网卡参到文本控件数命令失败 下发命令={}", devCode, ByteUtil.byteArrToHexString(datas, true));
					}
				}

			});
		} else {
			logger.error("{} 主机没有找到指定channel", devCode);
		}
	}

	/**
	 * 创建更新文本控件的消息
	 * 
	 * @param screenId
	 * @param controlId
	 * @param text
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private byte[] createUpdateTextControlMessage(byte[] devAddress, byte screenId, byte ipControlId, String ipContent,
			byte maskControlId, String maskContent, byte gatewayControlId, String gatewayContent,
			byte serverIpControlId, String serverIpContent,
			byte portControlId, String port)
			throws UnsupportedEncodingException {
		byte[] bIpContent = ipContent.getBytes(STRING_CODE);
		byte[] bServerIpContent = serverIpContent.getBytes(STRING_CODE);
		byte[] bServerPortContent =port.getBytes(STRING_CODE);
		byte[] bMaskContent = maskContent.getBytes(STRING_CODE);
		byte[] gGatewayContent = gatewayContent.getBytes(STRING_CODE);
		byte[] destDatas = new byte[bIpContent.length + bMaskContent.length + gGatewayContent.length+bServerIpContent.length+bServerPortContent.length + 29];
		destDatas[0] = (byte) 0xEE;
		destDatas[1] = (byte) 0xB1;
		destDatas[2] = (byte) 0x12;
		destDatas[3] = (byte) 0x00;
		destDatas[4] = screenId;
		destDatas[5] = (byte) 0x00;
		destDatas[6] = ipControlId;
		System.arraycopy(ByteUtil.shortToByteArr(Integer.valueOf(bIpContent.length).shortValue()), 0, destDatas, 7, 2);
		System.arraycopy(bIpContent, 0, destDatas, 9, bIpContent.length);
		int offset = 9 + bIpContent.length;

		destDatas[offset] = (byte) 0x00;
		destDatas[offset + 1] = maskControlId;
		offset += 2;
		System.arraycopy(ByteUtil.shortToByteArr(Integer.valueOf(bMaskContent.length).shortValue()), 0, destDatas,
				offset, 2);
		offset += 2;
		System.arraycopy(bMaskContent, 0, destDatas, offset, bMaskContent.length);
		offset += bMaskContent.length;

		destDatas[offset] = (byte) 0x00;
		destDatas[offset + 1] = gatewayControlId;
		offset += 2;
		System.arraycopy(ByteUtil.shortToByteArr(Integer.valueOf(gGatewayContent.length).shortValue()), 0, destDatas,
				offset, 2);
		offset += 2;
		System.arraycopy(gGatewayContent, 0, destDatas, offset, gGatewayContent.length);
		offset += gGatewayContent.length;

		// 设置服务器IP
				destDatas[offset] = (byte) 0x00;
				destDatas[++offset] = serverIpControlId;
				System.arraycopy(ByteUtil.shortToByteArr(Integer.valueOf(bServerIpContent.length).shortValue()), 0, destDatas, ++offset, 2);
				offset+=2;
				System.arraycopy(bServerIpContent, 0, destDatas, offset, bServerIpContent.length);
				offset += bServerIpContent.length;
				// 设置端口
				destDatas[offset] = (byte) 0x00;
				destDatas[offset+1] = portControlId;
				offset+=2;
				destDatas[offset] = (byte) 0x00;
				destDatas[offset+1] = Integer.valueOf(bServerPortContent.length).byteValue();
				offset+=2;
				System.arraycopy(bServerPortContent, 0, destDatas, offset, bServerPortContent.length);
				offset += bServerPortContent.length;
				
		destDatas[offset] = (byte) 0xFF;
		destDatas[offset + 1] = (byte) 0xFC;
		destDatas[offset + 2] = (byte) 0xFF;
		destDatas[offset + 3] = (byte) 0xFF;

		return destDatas;
	}

}
